/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_hdi_test_entry.h"
#include "sle_adapter_hdi.h"
#include "sle_ssap_client_hdi.h"
#include "sle_unit_test_log.h"

SleSsapcHdiCallbacks *g_ssapcHdiUtCbs;
SleSsapcHdiOpts *g_ssapcHdiUtOpts = NULL;
static uint16_t g_connectId = 1;
static uint8_t g_clientId = 65535;
static SleUuid g_appUuid = {
    .len = 16,
};

void OnSleHdiUtSleHdiSsapcFindStructureCallback(uint8_t clientId, uint16_t connectId,
    ClientFindServiceRes *Service, SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSleHdiSsapcFindStructureCallback");
}

static uint16_t g_propertyHandle;
void OnSleHdiUtSsapcFindPropertyCallback(uint8_t clientId, uint16_t connectId,
    ClientFindPropertyRes *property, SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcFindPropertyCallback");
    g_propertyHandle = property->handle;
}

void OnSleHdiUtSleHdiSsapcFindStructureCompleteCallback(uint8_t clientId, uint16_t connectId,
    ClientFindStructureRes *StructureResult, SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSleHdiSsapcFindStructureCompleteCallback");
}

void  OnSleHdiUtSsapcReadConformCallback(uint8_t clientId, uint16_t connectId, ClientHandleValue *readData,
    SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcReadConformCallback");
}

void OnSleHdiUtSsapcReadByUuidCompleteCallback(uint8_t clientId, uint16_t connectId,
    ClientReadByUuidCmpRes *cmpResult, SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcReadByUuidCompleteCallback");
}

void OnSleHdiUtSsapcWriteConformCallback(uint8_t clientId, uint16_t connectId, ClientWriteRes *writeResult,
    SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcWriteConformCallback");
}

void OnSleHdiUtSsapcExchangeInfoCallback(uint8_t clientId, uint16_t connectId, SsapMtuInfo *param,
    SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcExchangeInfoCallback");
}

void OnSleHdiUtSsapcNotificationCallback(uint8_t clientId, uint16_t connectId, ClientHandleValue *data,
    SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcNotificationCallback");
}

void OnSleHdiUtSsapcIndicationCallback(uint8_t clientId, uint16_t connectId, ClientHandleValue *data,
    SleHdiErrorCode res)
{
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED]OnSleHdiUtSsapcIndicationCallback");
}

void GetSleSsapcHdiOptsTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = GetSleSsapcHdiOpts(g_ssapcHdiUtOpts);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]GetSleSsapcHdiOptsTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] GetSleSsapcHdiOptsTestLevel0 pass");
}

void SleHdiRegisterSsapcCallbacksTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapcHdiUtOpts->registerClientCbks(g_ssapcHdiUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiRegisterSsapcCallbacksTestLevel0 failed(%08X)", ret);
     SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiRegisterSsapcCallbacksTestLevel0 pass");
}

void SleHdiSsapcRegisterClientTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapcHdiUtOpts->registerClient(&g_appUuid, &g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcRegisterClientTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcRegisterClientTestLevel0 pass");
}

void SleHdiSsapcUnregisterClientTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapcHdiUtOpts->unregisterClient(g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcUnregisterClientTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcUnregisterClientTestLevel0 pass");
}

void SleHdiSsapcFindStructureTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ClientFindStructure paramFind = {
        .findType  = SSAP_FIND_TYPE_PRIMARY_SERVICE_TYPE,
        .startHandle = 1,
        .endHandle = 0xFFFF,
        .uuid = g_appUuid,
    };
    ret = g_ssapcHdiUtOpts->findStructure(g_clientId, g_connectId, &paramFind);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcFindStructureTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcFindStructureTestLevel0 pass");
}

void SleHdiSsapcReadReqByUuidTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ClientReadReqByUUID redReqByUuid = {
        .findType  = SSAP_FIND_TYPE_PRIMARY_SERVICE_TYPE,
        .startHandle = 1,
        .endHandle = 0xFFFF,
        .uuid = g_appUuid,
    };
    ret = g_ssapcHdiUtOpts->readReqByUuid(g_clientId, g_connectId, &redReqByUuid);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcReadReqByUuidTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcReadReqByUuidTestLevel0 pass");
}

void SleHdiSsapcReadReqTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapcHdiUtOpts->readReq(g_clientId, g_connectId, g_propertyHandle, SLE_SSAP_PROPERTY_TYPE);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcReadReqTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcReadReqTestLevel0 pass");
}

void SleHdiSsapcWriteReqTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    };
    ret = g_ssapcHdiUtOpts->writeReq(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcWriteReqTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcWriteReqTestLevel0 pass");
}

void SleHdiSsapcWriteCmdTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    };
    ret = g_ssapcHdiUtOpts->writeCmd(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcWriteCmdTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcWriteCmdTestLevel0 pass");
}

void SleHdiSsapcExchangeInfoReqTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    SsapMtuInfo exchangeInfo = {
        .mtuSize = 300,
    };
    ret = g_ssapcHdiUtOpts->exchangeInfoReq(g_clientId, g_connectId, &exchangeInfo);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapcHdiTest][FAIL]SleHdiSsapcExchangeInfoReqTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapcHdiTest][PASSED] SleHdiSsapcExchangeInfoReqTestLevel0 pass");
}

void SleSsapcHdiTestLevel0(void)
{
    GetSleSsapcHdiOptsTestLevel0();
    SleHdiRegisterSsapcCallbacksTestLevel0();
    SleHdiSsapcRegisterClientTestLevel0();
    SleHdiSsapcExchangeInfoReqTestLevel0();
    SleHdiSsapcFindStructureTestLevel0();
    sleep(1);
    SleHdiSsapcWriteReqTestLevel0();
    SleHdiSsapcReadReqByUuidTestLevel0();
    SleHdiSsapcWriteCmdTestLevel0();
    SleHdiSsapcReadReqTestLevel0();
    SleHdiSsapcUnregisterClientTestLevel0();
}

SleHdiErrorCode InitSleSsapcHdiTestEntry(void)
{
    g_ssapcHdiUtCbs = (SleSsapcHdiOpts*)malloc(sizeof(SleSsapcHdiOpts));
    SLE_UT_CHECK_AND_RETURN_RET_LOG(g_ssapcHdiUtCbs != NULL, SLE_HDI_ERRCODE_FAIL, "[SleSsapcHdiTest][FAILED]InitSleSsapcHdiTestEntry malloc failed1");
    g_ssapcHdiUtOpts = (SleSsapcHdiOpts*)malloc(sizeof(SleSsapcHdiOpts));
    SLE_UT_CHECK_AND_RETURN_RET_LOG(g_ssapcHdiUtOpts != NULL, SLE_HDI_ERRCODE_FAIL, "[SleSsapcHdiTest][FAILED]InitSleSsapcHdiTestEntry memset failed2");
    g_ssapcHdiUtCbs->OnStructureFoundCb = OnSleHdiUtSleHdiSsapcFindStructureCallback;
    g_ssapcHdiUtCbs->OnPropertyFoundCb = OnSleHdiUtSsapcFindPropertyCallback;
    g_ssapcHdiUtCbs->OnFindStructureCmpCb = OnSleHdiUtSleHdiSsapcFindStructureCompleteCallback;
    g_ssapcHdiUtCbs->OnRecvReadResponseCb = OnSleHdiUtSsapcReadConformCallback;
    g_ssapcHdiUtCbs->OnRreadByUuidCmpCb = OnSleHdiUtSsapcReadByUuidCompleteCallback;
    g_ssapcHdiUtCbs->OnRecvWriteResponseCb = OnSleHdiUtSsapcWriteConformCallback;
    g_ssapcHdiUtCbs->OnExchangeInfoCb = OnSleHdiUtSsapcExchangeInfoCallback;
    g_ssapcHdiUtCbs->OnRecvNotificationCb = OnSleHdiUtSsapcNotificationCallback;
    g_ssapcHdiUtCbs->OnRecvNotificationCb = OnSleHdiUtSsapcIndicationCallback;
    uint8_t uuid[UUID_LEN] = {1};
    memcpy(g_appUuid.uuid, uuid, UUID_LEN);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode DeinitSleSsapcHdiTestEntry(void)
{
    free(g_ssapcHdiUtOpts);
    free(g_ssapcHdiUtCbs);
    return SLE_HDI_ERRCODE_SUCC;
}

void SleSsapcHdiTestEntry(void)
{
    SLE_UT_LOG("__SleSsapcHdiTestEntry start");
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = InitSleSsapcHdiTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HDI_ERRCODE_SUCC);
    SleSsapcHdiTestLevel0();
    // SleSsapcHdiTestLevel1();
    ret = DeinitSleSsapcHdiTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HDI_ERRCODE_SUCC);
    SLE_UT_LOG("__SleSsapcHdiTestEntry end");
}